//package com.hsc.www.plugin;
//
//import net.sf.jsqlparser.JSQLParserException;
//import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.schema.Table;
//import net.sf.jsqlparser.statement.select.Join;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.statement.select.SubSelect;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//import java.lang.reflect.Method;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Properties;
//
//@Intercepts({
//        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
//})
//public class PermissionHelper1 implements Interceptor {
//    private Logger log = LoggerFactory.getLogger(PageHelper.class);
//    static int MAPPED_STATEMENT_INDEX = 0;// 这是对应上面的args的序号
//    static int PARAMETER_INDEX = 1;
//    static int ROWBOUNDS_INDEX = 2;
//    static int RESULT_HANDLER_INDEX = 3;
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//
//        Object target = invocation.getTarget(); //被代理对象
//        Method method = invocation.getMethod(); //代理方法
//        Object[] args = invocation.getArgs(); //方法参数
//
//
//        final Object[] queryArgs = invocation.getArgs();
//        final MappedStatement mappedStatement = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
//        final Object parameter = queryArgs[PARAMETER_INDEX];
//        final BoundSql boundSql = mappedStatement.getBoundSql(parameter);
//
//        String sql = boundSql.getSql();
//
//        PermissionRule permissionRule = new PermissionRule();
//        permissionRule.setFromEntity("student");
//        permissionRule.setRoles("user");
//        List<PermissionRule> lit = new ArrayList<>();
//        lit.add(permissionRule);
//        Principal principal = new Principal();
//        principal.setId("123456");
//        principal.setRoles(Arrays.asList("user"));
//        processSelectSql(sql, lit, principal);
//        return null;
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        return Plugin.wrap(target, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//
//    }
//
//
//    public static String processSelectSql(String sql, List<PermissionRule> rules, Principal principal) {
//        try {
//            String replaceSql = null;
//            Select select = (Select) CCJSqlParserUtil.parse(sql);
//            PlainSelect selectBody = (PlainSelect) select.getSelectBody();
//            String mainTable = null;
//            if (selectBody.getFromItem() instanceof Table) {
//                mainTable = ((Table) selectBody.getFromItem()).getName().replace("`", "");
//            } else if (selectBody.getFromItem() instanceof SubSelect) {
//                replaceSql = processSelectSql(((SubSelect) selectBody.getFromItem()).getSelectBody().toString(), rules, principal);
//            }
//            if (replaceSql != null && !"".equals(replaceSql.trim())) {
//                sql = sql.replace(((SubSelect) selectBody.getFromItem()).getSelectBody().toString(), replaceSql);
//            }
//            String mainTableAlias = mainTable;
//            try {
//                mainTableAlias = selectBody.getFromItem().getAlias().getName();
//            } catch (Exception e) {
////                log.debug("当前sql中， " + mainTable + " 没有设置别名");
//            }
//            String condExpr = null;
//            PermissionRule realRuls = null;
//            for (PermissionRule rule : rules) {
//                for (Object roleStr : principal.getRoles()) {
//                    if (rule.getRoles().indexOf("," + roleStr + ",") != -1) {
//                        if (rule.getFromEntity().indexOf("," + mainTable + ",") != -1) {
//                            // 若主表匹配规则主体，则直接使用本规则
//                            realRuls = rule;
//                            condExpr = rule.getExps().replace("{uid}", principal.getId()).replace("{me}", mainTable).replace("{me.a}", mainTableAlias);
//                            if (selectBody.getWhere() == null) {
//                                selectBody.setWhere(CCJSqlParserUtil.parseCondExpression(condExpr));
//                            } else {
//                                AndExpression and = new AndExpression(selectBody.getWhere(), CCJSqlParserUtil.parseCondExpression(condExpr));
//                                selectBody.setWhere(and);
//                            }
//                        }
//                        try {
//                            String joinTable = null;
//                            String joinTableAlias = null;
//                            for (Join j : selectBody.getJoins()) {
//                                if (rule.getFromEntity().indexOf("," + ((Table) j.getRightItem()).getName() + ",") != -1) {
//                                    // 当主表不能匹配时，匹配所有join，使用符合条件的第一个表的规则。
//                                    realRuls = rule;
//                                    joinTable = ((Table) j.getRightItem()).getName();
//                                    joinTableAlias = j.getRightItem().getAlias().getName();
//                                    condExpr = rule.getExps().replace("{uid}", principal.id).replace("{me}", joinTable).replace("{me.a}", joinTableAlias);
//                                    if (j.getOnExpression() == null) {
//                                        j.setOnExpression(CCJSqlParserUtil.parseCondExpression(condExpr));
//                                    } else {
//                                        AndExpression and = new AndExpression(j.getOnExpression(), CCJSqlParserUtil.parseCondExpression(condExpr));
//                                        j.setOnExpression(and);
//                                    }
//                                }
//                            }
//                        } catch (Exception e) {
////                            log.debug("当前sql没有join的部分！");
//                        }
//                    }
//                }
//            }
//            if (realRuls == null) return sql; // 没有合适规则直接退出。
//            if (sql.indexOf("limit ?,?") != -1 && select.toString().indexOf("LIMIT ? OFFSET ?") != -1) {
//                sql = select.toString().replace("LIMIT ? OFFSET ?", "limit ?,?");
//            } else {
//                sql = select.toString();
//            }
//        } catch (JSQLParserException e) {
////            log.error("change sql error .", e);
//        }
//        return sql;
//    }
//
//    public static class Principal {
//
//        private String id;
//        private String name;
//
//
//        private List<String> roles;
//
//        public List<String> getRoles() {
//            return roles;
//        }
//
//        public void setRoles(List<String> roles) {
//            this.roles = roles;
//        }
//
//        public String getId() {
//            return id;
//        }
//
//        public void setId(String id) {
//            this.id = id;
//        }
//
//        public String getName() {
//            return name;
//        }
//
//        public void setName(String name) {
//            this.name = name;
//        }
//    }
//
//
//    public static class PermissionRule {
//        private Logger log = LoggerFactory.getLogger(PageHelper.class);
//        /**
//         * codeName<br>
//         * 适用角色列表<br>
//         * 格式如: ,RoleA,RoleB,
//         */
//        private String roles;
//        /**
//         * codeValue<br>
//         * 主实体，多表联合
//         * 格式如: ,SystemCode,User,
//         */
//        private String fromEntity;
//        /**
//         * codeDesc<br>
//         * 过滤表达式字段, <br>
//         * <code>{uid}</code>会自动替换为当前用户的userId<br>
//         * <code>{me}</code> main entity 主实体名称
//         * <code>{me.a}</code> main entity alias 主实体别名
//         * 格式如：
//         * <ul>
//         * <li>userId = {uid}</li>
//         * <li>(userId = {uid} AND authType > 3)</li>
//         * <li>((userId = {uid} AND authType) > 3 OR (dept in (select dept from depts where manager.id = {uid})))</li>
//         * </ul>
//         */
//        private String exps;
//
//        /**
//         * codeShowName<br>
//         * 规则说明
//         */
//        private String ruleComment;
//
//        public Logger getLog() {
//            return log;
//        }
//
//        public void setLog(Logger log) {
//            this.log = log;
//        }
//
//        public String getRoles() {
//            return roles;
//        }
//
//        public void setRoles(String roles) {
//            this.roles = roles;
//        }
//
//        public String getFromEntity() {
//            return fromEntity;
//        }
//
//        public void setFromEntity(String fromEntity) {
//            this.fromEntity = fromEntity;
//        }
//
//        public String getExps() {
//            return exps;
//        }
//
//        public void setExps(String exps) {
//            this.exps = exps;
//        }
//
//        public String getRuleComment() {
//            return ruleComment;
//        }
//
//        public void setRuleComment(String ruleComment) {
//            this.ruleComment = ruleComment;
//        }
//    }
//}
